use super::*;

pub struct AfterTimes {
    count: u32,
    frames: u32,
}

impl AfterTimes {
    pub fn new(frames: u32) -> Box<Self> {
        Box::new(Self {
            count: 0,
            frames,
        })
    }
}

impl ICondition for AfterTimes {
    fn check(&mut self) -> bool {
        self.count += 1;
        self.count > self.frames
    }

    fn reset(&mut self) {
        self.count = 0;
    }
}

pub struct Intermittent {
    count: u32,
    interval: u32,
}

impl Intermittent {
    pub fn new(interval_frame: u32) -> Box<Self> {
        Box::new(Self {
            count: 0,
            interval: interval_frame,
        })
    }
}

impl ICondition for Intermittent {
    fn check(&mut self) -> bool {
        self.count += 1;
        if self.count >= self.interval {
            self.count = 0;
            true
        } else {
            false
        }
    }

    fn reset(&mut self) {
        self.count = 0;
    }
}

pub struct AfterIterator<I: Iterator, F: FnMut(I::Item)> {
    iter: I,
    op: F,
}

impl<I: Iterator, F: FnMut(I::Item)> AfterIterator<I, F> {
    pub fn new(iter: I, op: F) -> Box<Self> {
        Box::new(Self {
            iter,
            op,
        })
    }
}

impl<I: Iterator, F: FnMut(I::Item)> ICondition for AfterIterator<I, F> {
    fn check(&mut self) -> bool {
        if let Some(item) = self.iter.next() {
            (self.op)(item);
            false
        } else {
            true
        }
    }

    fn reset(&mut self) {
        // Will not be reset, because iter was consumed.
    }
}